#include "BlockQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
#include <ctime>

using namespace yss;
using BlockQueue_t = BlockQueue<Task>;

//消费
void Consumer(BlockQueue_t &bq)//引用是为了使用同一个队列
{
    while (true)
    {
        // 取出任务
        Task t;
        bq.Pop(&t);
        // 执行任务
        t.Excute();
        cout << "Consumer: " << t.RTostring() << endl;
    }
}
//生产
void Productor(BlockQueue_t &bq)
{
    srand(time(nullptr));
    while (true)
    {
        // 获取任务
        int a = rand() % 10 + 1;
        usleep(1000);
        int b = rand() % 20 + 1;
        Task t(a, b);
        // 将任务放入队列
        bq.Enqueue(t);
        cout << "Productor: " << t.DTostring() << endl;
        sleep(1);
    }
}
// 共用代码
void StartComm(vector<Thread<BlockQueue_t>> *thread, int num, BlockQueue_t &bq, func_t<BlockQueue_t> func)
{
    for (int i = 0; i < num; i++)
    {
        string name = "thread-" + to_string(i + 1);
        thread->emplace_back(func, bq, name); // 保存数据
        thread->back().Satrt();               // 创建线程
    }
}
// 消费者
void StartConsumer(vector<Thread<BlockQueue_t>> *thread, int num, BlockQueue_t &bq)
{
    StartComm(thread, num, bq, Consumer); // 复用
}
// 生产者
void StartProductor(vector<Thread<BlockQueue_t>> *thread, int num, BlockQueue_t &bq)
{
    StartComm(thread, num, bq, Productor); // 复用
}
// 等待
void WaitAllThread(vector<Thread<BlockQueue_t>> &threads)
{
    for (auto &t : threads)
    {
        t.Join();
    }
}
int main()
{
    BlockQueue_t *bq = new BlockQueue_t(5);//阻塞队列
    vector<Thread<BlockQueue_t>> threads;
    StartProductor(&threads, 1, *bq); // 单生产 -- bq是传引用，保证同一个
    StartConsumer(&threads, 1, *bq);  // 单消费
    WaitAllThread(threads); // 等待
    return 0;
}